package com.icesoft.xsnow.oauth.config;

import com.icesoft.xsnow.common.core.constant.SecurityConstants;
import com.icesoft.xsnow.oauth.constants.PermitAllUrl;
import com.icesoft.xsnow.oauth.service.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**
 * @program: xsnow
 * @description: 用户安全配置
 * @author: xuefeng.gao
 * @create: 2019-05-10 11:29
 **/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true,jsr250Enabled = true)
@Order(90)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
    @Autowired
    UserDetailsServiceImpl  userDetailsService;

    /**
    *  用户配置
    **/
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //模拟测试数据 结束
        auth.userDetailsService(userDetailsService);
    }



    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                // 配置服务器允许 /oauth/token的 OPTIONS 方法
                // 因为 /oauth/token 接口是先发一个 OPTIONS 请求，然后再发送 POST请求，如果是 OPTIONS 接口不被允许，就会返回 401 错误
                .antMatchers(HttpMethod.OPTIONS,"/oauth/token").permitAll()
                // 放开权限的url
                .antMatchers(PermitAllUrl.permitAllUrl()).permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                // 自定义登陆请求
                .loginPage(SecurityConstants.LOGIN_PAGE)
                // 自定义表单登陆地址
                .loginProcessingUrl(SecurityConstants.LOGIN_PROCESS_URL)
//                .and()
//                .logout().logoutUrl(SecurityConstants.LOGOUT_URL)
                .and()
                .cors()
                .and()
                //3.Basic Csrf 关闭
                .csrf().disable();
    }


    /**
    *
    **/
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/oauth/check_token");
    }

    /**
     *  加密方式
     **/
    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        return  new BCryptPasswordEncoder();
    }

    @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}
